#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
PyQt6 Socket服务器页面
提供TCP/UDP服务器功能，包括客户端管理和数据发送
"""

from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
                             QGroupBox, QPushButton, QLabel, QLineEdit,
                             QComboBox, QRadioButton, QScrollArea,
                             QListWidget, QFrame, QApplication, QTextEdit)
from PyQt6.QtCore import pyqtSignal, Qt, QTimer
from PyQt6.QtGui import QFont

from utils.communication import TcpServerManager, UdpServerManager
from gui.components.pyqt6_log_component import PyQt6LogComponent


class SocketServerPage(QWidget):
    """Socket服务器页面类"""
    
    def __init__(self):
        """初始化Socket服务器页面"""
        super().__init__()
        self.title = "Socket服务器"
        
        # 初始化通信管理器
        self.tcp_server_manager = TcpServerManager(self._server_message_callback)
        self.udp_server_manager = UdpServerManager(self._server_message_callback)
        
        # 客户端刷新定时器
        self.client_refresh_timer = None
        
        # 初始化界面
        self._init_ui()
    
    def _init_ui(self):
        """初始化UI界面"""
        # 设置主布局
        main_layout = QHBoxLayout(self)
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(15)
        
        # 左侧控制面板
        control_panel = self._create_control_panel()
        main_layout.addWidget(control_panel, 1)
        
        # 右侧日志面板
        log_panel = self._create_log_panel()
        main_layout.addWidget(log_panel, 3)
        
        # 设置整体样式
        self._setup_styles()
    
    def _setup_styles(self):
        """设置界面样式"""
        # 设置字体
        font = QFont("Arial", 10)
        self.setFont(font)

        # 为所有控件设置统一字体
        for widget in self.findChildren(QWidget):
            if isinstance(widget, (QLabel, QLineEdit, QPushButton, QTextEdit)):
                widget.setFont(font)

        # 为所有GroupBox设置样式
        for group_box in self.findChildren(QGroupBox):
            group_box.setStyleSheet("""
                QGroupBox {
                    font-weight: bold;
                    border: 1px solid gray;
                    border-radius: 5px;
                    margin-top: 1ex;
                }
                QGroupBox::title {
                    subline-offset: -2px;
                    padding: 0 5px;
                }
            """)

        # 为所有控件设置样式
        for line_edit in self.findChildren(QLineEdit):
            line_edit.setStyleSheet("""
                QLineEdit {
                    padding: 8px;
                    border: 1px solid #ccc;
                    border-radius: 4px;
                    font-size: 10px;
                }
            """)

        for push_button in self.findChildren(QPushButton):
            push_button.setStyleSheet("""
                QPushButton {
                    background-color: #2196F3;
                    color: white;
                    border: none;
                    padding: 12px;
                    border-radius: 4px;
                    font-weight: bold;
                    font-size: 10px;
                }
                QPushButton:hover {
                    background-color: #1976D2;
                }
                QPushButton:pressed {
                    background-color: #0D47A1;
                }
            """)

        for label in self.findChildren(QLabel):
            label.setStyleSheet("""
                QLabel {
                    color: #333;
                    font-weight: bold;
                    font-size: 10px;
                }
            """)

        for list_widget in self.findChildren(QListWidget):
            list_widget.setStyleSheet("""
                QListWidget {
                    border: 1px solid #ccc;
                    border-radius: 4px;
                    padding: 5px;
                    font-size: 10px;
                }
            """)
    
    def _create_control_panel(self):
        """创建控制面板"""
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)

        container = QWidget()
        layout = QVBoxLayout(container)
        layout.setSpacing(15)

        # 协议选择组
        protocol_group = QGroupBox("协议选择")
        protocol_layout = QVBoxLayout(protocol_group)
        protocol_layout.setSpacing(8)

        self.tcp_radio = QRadioButton("TCP服务器")
        self.udp_radio = QRadioButton("UDP服务器")
        self.tcp_radio.setChecked(True)

        # 设置RadioButton样式
        self.tcp_radio.setStyleSheet("""
            QRadioButton {
                spacing: 5px;
            }
            QRadioButton::indicator {
                width: 18px;
                height: 18px;
            }
        """)

        self.udp_radio.setStyleSheet("""
            QRadioButton {
                spacing: 5px;
            }
            QRadioButton::indicator {
                width: 18px;
                height: 18px;
            }
        """)

        self.tcp_radio.toggled.connect(self._on_protocol_change)
        self.udp_radio.toggled.connect(self._on_protocol_change)

        protocol_layout.addWidget(self.tcp_radio)
        protocol_layout.addWidget(self.udp_radio)

        # 服务器配置组
        config_group = QGroupBox("服务器配置")
        config_layout = QGridLayout(config_group)
        config_layout.setSpacing(12)
        config_layout.setContentsMargins(10, 15, 10, 15)
        
        ip_label = QLabel("监听IP:")
        ip_label.setStyleSheet("QLabel { font-weight: bold; }")
        config_layout.addWidget(ip_label, 0, 0)
        self.host_edit = QLineEdit("0.0.0.0")
        self.host_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        config_layout.addWidget(self.host_edit, 0, 1)
        
        port_label = QLabel("端口:")
        port_label.setStyleSheet("QLabel { font-weight: bold; }")
        config_layout.addWidget(port_label, 1, 0)
        self.port_edit = QLineEdit("9010")
        self.port_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        config_layout.addWidget(self.port_edit, 1, 1)
        
        self.start_btn = QPushButton("启动TCP服务器")
        self.start_btn.setStyleSheet("""
            QPushButton {
                background-color: #2196F3;
                color: white;
                border: none;
                padding: 12px;
                border-radius: 4px;
                font-weight: bold;
                font-size: 11px;
            }
            QPushButton:hover {
                background-color: #1976D2;
            }
            QPushButton:pressed {
                background-color: #0D47A1;
            }
        """)
        self.start_btn.clicked.connect(self._start_server)
        config_layout.addWidget(self.start_btn, 2, 0, 1, 2)
        
        # 状态信息组
        status_group = QGroupBox("状态信息")
        status_layout = QVBoxLayout(status_group)
        status_layout.setSpacing(8)
        
        self.status_label = QLabel("服务器: 未启动")
        self.address_label = QLabel("监听地址: -")
        self.client_count_label = QLabel("连接数: 0")
        
        # 设置状态标签样式
        self.status_label.setStyleSheet("""
            QLabel {
                color: #333;
                font-weight: bold;
            }
        """)
        
        self.address_label.setStyleSheet("""
            QLabel {
                color: #333;
                font-weight: bold;
            }
        """)
        
        self.client_count_label.setStyleSheet("""
            QLabel {
                color: #333;
                font-weight: bold;
            }
        """)
        
        status_layout.addWidget(self.status_label)
        status_layout.addWidget(self.address_label)
        status_layout.addWidget(self.client_count_label)
        
        # 客户端管理组
        client_group = QGroupBox("客户端管理")
        client_layout = QVBoxLayout(client_group)
        client_layout.setSpacing(8)
        
        client_layout.addWidget(QLabel("客户端列表:"))
        self.client_list_widget = QListWidget()
        self.client_list_widget.setStyleSheet("""
            QListWidget {
                border: 1px solid #ccc;
                border-radius: 4px;
                padding: 5px;
            }
        """)
        client_layout.addWidget(self.client_list_widget)
        
        # 客户端操作按钮
        client_btn_layout = QHBoxLayout()
        refresh_btn = QPushButton("刷新列表")
        refresh_btn.setStyleSheet("""
            QPushButton {
                background-color: #FF9800;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #F57C00;
            }
            QPushButton:pressed {
                background-color: #EF6C00;
            }
        """)
        refresh_btn.clicked.connect(self._refresh_client_list)
        disconnect_selected_btn = QPushButton("断开选中")
        disconnect_selected_btn.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #d32f2f;
            }
            QPushButton:pressed {
                background-color: #b71c1c;
            }
        """)
        disconnect_selected_btn.clicked.connect(self._disconnect_selected)
        disconnect_all_btn = QPushButton("断开全部")
        disconnect_all_btn.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #d32f2f;
            }
            QPushButton:pressed {
                background-color: #b71c1c;
            }
        """)
        disconnect_all_btn.clicked.connect(self._disconnect_all)
        
        client_btn_layout.addWidget(refresh_btn)
        client_btn_layout.addWidget(disconnect_selected_btn)
        client_btn_layout.addWidget(disconnect_all_btn)
        client_layout.addLayout(client_btn_layout)
        
        # 数据发送组
        send_group = QGroupBox("数据发送")
        send_layout = QVBoxLayout(send_group)
        send_layout.setSpacing(10)
        
        send_layout.addWidget(QLabel("发送数据:"))
        self.send_data_edit = QLineEdit("01 03 00 00 00 06")
        self.send_data_edit.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        send_layout.addWidget(self.send_data_edit)
        
        send_selected_btn = QPushButton("发送到选中客户端")
        send_selected_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:pressed {
                background-color: #3d8b40;
            }
        """)
        send_selected_btn.clicked.connect(self._send_to_selected)
        send_layout.addWidget(send_selected_btn)
        
        broadcast_btn = QPushButton("广播到所有客户端")
        broadcast_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 10px;
                border-radius: 4px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
            QPushButton:pressed {
                background-color: #3d8b40;
            }
        """)
        broadcast_btn.clicked.connect(self._broadcast_data)
        send_layout.addWidget(broadcast_btn)
        
        # 添加到主布局
        layout.addWidget(protocol_group)
        layout.addWidget(config_group)
        layout.addWidget(status_group)
        layout.addWidget(client_group)
        layout.addWidget(send_group)
        layout.addStretch()
        
        scroll_area.setWidget(container)
        return scroll_area
    
    def _create_log_panel(self):
        """创建日志面板"""
        self.log_component = PyQt6LogComponent(self, "服务器日志", 20)
        return self.log_component
    
    def _on_protocol_change(self):
        """协议切换事件处理"""
        if self.tcp_radio.isChecked():
            self.port_edit.setText("9010")
            self.start_btn.setText("启动TCP服务器")
        else:  # UDP
            self.port_edit.setText("9020")
            self.start_btn.setText("启动UDP服务器")
    
    def _start_server(self):
        """启动服务器"""
        try:
            host = self.host_edit.text().strip()
            port = int(self.port_edit.text().strip())
            
            if self.tcp_radio.isChecked():
                success = self.tcp_server_manager.start_server(host, port)
                if success:
                    self.status_label.setText("TCP服务器: 运行中")
                    self.start_btn.setText("停止TCP服务器")
                    self.start_btn.clicked.disconnect()
                    self.start_btn.clicked.connect(self._stop_server)
            else:  # UDP
                success = self.udp_server_manager.start_server(host, port)
                if success:
                    self.status_label.setText("UDP服务器: 运行中")
                    self.start_btn.setText("停止UDP服务器")
                    self.start_btn.clicked.disconnect()
                    self.start_btn.clicked.connect(self._stop_server)
            
            if success:
                self.address_label.setText(f"监听地址: {host}:{port}")
                self._start_client_refresh_timer()
                self.log_component.log_message(f"服务器启动成功: {host}:{port}")
            else:
                self.log_component.log_message("启动服务器失败", "ERROR")
                
        except Exception as e:
            self.log_component.log_message(f"启动服务器失败: {e}", "ERROR")
    
    def _stop_server(self):
        """停止服务器"""
        try:
            if self.tcp_radio.isChecked():
                self.tcp_server_manager.stop_server()
                self.start_btn.setText("启动TCP服务器")
                self.start_btn.clicked.disconnect()
                self.start_btn.clicked.connect(self._start_server)
            else:  # UDP
                self.udp_server_manager.stop_server()
                self.start_btn.setText("启动UDP服务器")
                self.start_btn.clicked.disconnect()
                self.start_btn.clicked.connect(self._start_server)
            
            self._stop_client_refresh_timer()
            self.status_label.setText("服务器: 未启动")
            self.address_label.setText("监听地址: -")
            self.client_count_label.setText("连接数: 0")
            self.client_list_widget.clear()
            self.log_component.log_message("服务器已停止")
            
        except Exception as e:
            self.log_component.log_message(f"停止服务器错误: {e}", "ERROR")
    
    def _start_client_refresh_timer(self):
        """启动客户端列表刷新定时器"""
        self._refresh_client_list()
        self.client_refresh_timer = QTimer()
        self.client_refresh_timer.timeout.connect(self._refresh_client_list)
        self.client_refresh_timer.start(3000)  # 3秒刷新一次
    
    def _stop_client_refresh_timer(self):
        """停止客户端列表刷新定时器"""
        if self.client_refresh_timer:
            self.client_refresh_timer.stop()
            self.client_refresh_timer = None
    
    def _refresh_client_list(self):
        """刷新客户端列表"""
        try:
            self.client_list_widget.clear()
            
            if self.tcp_radio.isChecked():
                if self.tcp_server_manager.is_running():
                    client_list = self.tcp_server_manager.get_client_list()
                    client_count = self.tcp_server_manager.get_client_count()
                else:
                    client_list = []
                    client_count = 0
            else:  # UDP
                if self.udp_server_manager.running:
                    client_list = [(i+1, addr, "在线") for i, addr in enumerate(self.udp_server_manager.get_client_list())]
                    client_count = self.udp_server_manager.get_client_count()
                else:
                    client_list = []
                    client_count = 0
            
            # 更新客户端数量显示
            self.client_count_label.setText(f"连接数: {client_count}")
            
            # 更新客户端列表
            for client_id, address, status in client_list:
                display_text = f"[{client_id}] {address[0]}:{address[1]} ({status})"
                self.client_list_widget.addItem(display_text)
                
        except Exception as e:
            self.log_component.log_message(f"刷新客户端列表错误: {e}", "ERROR")
    
    def _disconnect_selected(self):
        """断开选中的客户端"""
        current_item = self.client_list_widget.currentItem()
        if not current_item:
            self.log_component.log_message("请先选择要断开的客户端", "WARNING")
            return
        
        # 解析选中的客户端信息
        selected_text = current_item.text()
        import re
        match = re.match(r'\[(\d+)\]', selected_text)
        if match:
            client_id = int(match.group(1))
            
            try:
                if self.tcp_radio.isChecked():
                    success = self.tcp_server_manager.disconnect_client(client_id)
                    if success:
                        self.log_component.log_message(f"已断开TCP客户端 [ID: {client_id}]")
                    else:
                        self.log_component.log_message(f"断开TCP客户端失败 [ID: {client_id}]", "ERROR")
                else:
                    self.log_component.log_message("UDP客户端无需主动断开连接", "INFO")
                
                self._refresh_client_list()
            except Exception as e:
                self.log_component.log_message(f"断开客户端错误: {e}", "ERROR")
    
    def _disconnect_all(self):
        """断开全部客户端"""
        try:
            if self.tcp_radio.isChecked():
                count = self.tcp_server_manager.disconnect_all_clients()
                self.log_component.log_message(f"已断开全部TCP客户端，共 {count} 个")
            else:
                self.log_component.log_message("UDP服务器无需主动断开客户端", "INFO")
            
            self._refresh_client_list()
        except Exception as e:
            self.log_component.log_message(f"断开全部客户端错误: {e}", "ERROR")
    
    def _send_to_selected(self):
        """向选中的客户端发送数据"""
        current_item = self.client_list_widget.currentItem()
        if not current_item:
            self.log_component.log_message("请先选择要发送数据的客户端", "WARNING")
            return
        
        data_input = self.send_data_edit.text().strip()
        if not data_input:
            self.log_component.log_message("请输入要发送的数据", "WARNING")
            return
        
        # 解析选中的客户端信息
        selected_text = current_item.text()
        import re
        match = re.match(r'\[(\d+)\]', selected_text)
        if match:
            client_id = int(match.group(1))
            
            try:
                if self.tcp_radio.isChecked():
                    success = self.tcp_server_manager.send_to_client(client_id, data_input)
                    if success:
                        self.log_component.log_message(f"发送到TCP客户端[{client_id}]: {data_input}", "INFO", "send")
                    else:
                        self.log_component.log_message(f"发送到TCP客户端[{client_id}]失败", "ERROR")
                else:  # UDP
                    client_list = self.udp_server_manager.get_client_list()
                    if client_id <= len(client_list):
                        client_address = client_list[client_id - 1]
                        byte_data, _, _ = self.udp_server_manager.parse_data_input(data_input)
                        success = self.udp_server_manager.send_to_client(client_address, byte_data)
                        if success:
                            self.log_component.log_message(f"发送到UDP客户端[{client_address}]: {data_input}", "INFO", "send")
                        else:
                            self.log_component.log_message(f"发送到UDP客户端[{client_address}]失败", "ERROR")
                    else:
                        self.log_component.log_message("客户端ID无效", "ERROR")
                        
            except Exception as e:
                self.log_component.log_message(f"发送数据失败: {e}", "ERROR")
    
    def _broadcast_data(self):
        """广播数据到所有客户端"""
        data_input = self.send_data_edit.text().strip()
        if not data_input:
            self.log_component.log_message("请输入要广播的数据", "WARNING")
            return
        
        try:
            if self.tcp_radio.isChecked():
                count = self.tcp_server_manager.broadcast_to_all(data_input)
                self.log_component.log_message(f"广播到{count}个TCP客户端: {data_input}", "INFO", "send")
            else:  # UDP
                byte_data, _, _ = self.udp_server_manager.parse_data_input(data_input)
                count = self.udp_server_manager.broadcast_to_all(byte_data)
                self.log_component.log_message(f"广播到{count}个UDP客户端: {data_input}", "INFO", "send")
                
        except Exception as e:
            self.log_component.log_message(f"广播数据失败: {e}", "ERROR")
    
    def _server_message_callback(self, message: str, level: str = "INFO", msg_type: str = "normal"):
        """服务器消息回调"""
        self.log_component.log_message(message, level, msg_type)
        
        # 更新客户端数量显示
        try:
            if self.tcp_radio.isChecked():
                count = self.tcp_server_manager.get_client_count()
            else:  # UDP
                count = self.udp_server_manager.get_client_count()
            self.client_count_label.setText(f"连接数: {count}")
        except:
            pass
    
    def on_close(self):
        """页面关闭时的清理"""
        self._stop_client_refresh_timer()
        try:
            self.tcp_server_manager.stop_server()
            self.udp_server_manager.stop_server()
        except:
            pass


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = SocketServerPage()
    window.show()
    sys.exit(app.exec())